from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django.core.cache import caches

from dashopt import settings
from goods.models import SKU
from utils.logging_dec import logging_check


class CartsView(View):
    @logging_check
    def post(self, request, username):
        """
        添加购物车视图逻辑
        Redis中存储的购物车数据结构如下
        "carts_1":{
            "1":[3,1],
            "2":[2,0],
            "3":[5,1],
        }
        """
        data = request.my_data
        sku_id = data.get("sku_id")
        count = data.get("count")
        count = int(count)
        # 获取该用户原来购物车的数据
        user = request.my_user
        key = f"carts_{user.id}"
        carts_dict = caches["carts"].get(key)
        # 如果为None 则赋值为空字典
        if not carts_dict:
            carts_dict = {}

        if len(carts_dict) > 100:
            return JsonResponse({
                "code": 10302,
                "error": "最多添加100种商品!"
            })

        if sku_id not in carts_dict:
            carts_dict[sku_id] = [count, 1]
        else:
            carts_dict[sku_id][0] += count
            carts_dict[sku_id][1] = 1
        # 把其他商品的状态都设置为0
        for sid in carts_dict:
            if sid != sku_id:
                carts_dict[sid][1] = 0

        # 更新到redis数据库中
        caches["carts"].set(key, carts_dict)
        result = {
            "code": 200,
            "data": {
                "carts_count": len(carts_dict)
            },
            "base_url": settings.PIC_URL
        }
        return JsonResponse(result)

    @logging_check
    def get(self, request, username):
        """
        查询购物车的视图逻辑
        1.从Redis中查询数据
        2.从Mysql中查询数据
        {"code":200,"skus_list":[],"base_url":"XXX"}
        """
        user_id = request.my_user.id
        carts_dict = self.get_carts_dict(user_id)
        skus_list = []
        for sku_id in carts_dict:
            sku = SKU.objects.get(id=sku_id)
            values = sku.sale_attr_value.all()
            sku_dict = {
                "id": sku.id,
                "name": sku.name,
                "count": carts_dict[sku_id][0],
                "selected": carts_dict[sku_id][1],
                "default_image_url": str(sku.default_image_url),
                "price": sku.price,
                "sku_sale_attr_name": [i.spu_sale_attr.name for i in values],
                "sku_sale_attr_val": [i.name for i in values]
            }

            skus_list.append(sku_dict)
        result = {
            "code": 200,
            "data": skus_list,
            "base_url": settings.PIC_URL
        }
        return JsonResponse(result)

    @logging_check
    def delete(self, request, username):
        """
        删除购物车视图逻辑
        1.获取请求体数据(sku_id)
        2.获取该用户购物车数据的字典,删除对应的key
        3.更新到Redis数据库
        4.返回响应
        """
        sku_id = request.my_data.get("sku_id")
        user_id = request.my_user.id
        carts_dict = self.get_carts_dict(user_id)
        try:
            carts_dict.pop(str(sku_id))
        except Exception as e:
            return JsonResponse({
                "code": 10301,
                "error": "该商品不存在"})
        # 更新到redis中
        self.update_carts(user_id, carts_dict)
        # 返回响应
        result = {
            "code": 200,
            "data": {
                "carts_count": len(carts_dict)
            },
            "base_url": settings.PIC_URL
        }
        return JsonResponse(result)

    @logging_check
    def put(self, request, username):
        """
        修改购物车的视图逻辑
        +1操作：add
        -1操作：del
        单选操作：select
        取消单选操作：unselect
        全选：selectall
        取消全选：unselectall
        """
        # 获取请求体的数据
        data = request.my_data
        sku_id = data.get("sku_id")
        state = data.get("state")
        # 获取购物车数据字典
        user_id = request.my_user.id
        carts_dict = self.get_carts_dict(user_id)
        # 修改字典,更新到redis数据库
        # {"1":[3,1],"2":[5,0]}
        if sku_id and sku_id not in carts_dict:
            return JsonResponse({"code": 10303, "error": "该商品不存在"})
        if state == "add":
            carts_dict[sku_id][0] += 1
        elif state == "del":
            if carts_dict[sku_id][0] > 1:
                carts_dict[sku_id][0] -= 1
            else:
                return JsonResponse({"code":10305,"error":"数量不能更少"})
        elif state == "select":
            carts_dict[sku_id][1] = 1
        elif state == "unselect":
            carts_dict[sku_id][1] = 0
        elif state == "selectall":
            for sid in carts_dict:
                carts_dict[sid][1] = 1
        elif state == "unselectall":
            for sid in carts_dict:
                carts_dict[sid][1] = 0
        else:
            return JsonResponse({"code": 10304, "error": "违法请求！"})
        # 更新到Redis 数据库
        self.update_carts(user_id, carts_dict)
        # 返回响应
        return JsonResponse({"code": 200})

    def get_carts_dict(self, user_id):
        """
        功能函数：获取购物车数据的字典
        """
        key = f'carts_{user_id}'
        carts_dict = caches["carts"].get(key)
        if not carts_dict:
            return {}
        return carts_dict

    def update_carts(self, user_id, carts_dict):
        """
        功能函数:更新Redis中购物车数据
        """
        key = f"carts_{user_id}"
        caches["carts"].set(key, carts_dict)
